package com.zjw.concurrency.juc.lock.reentrantLock;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/*
*演示读写锁的插队策略(模拟等待队列的写线程不是头结点时，读线程可以插队)
*
* */
public class UnfairReadWriteLock {

    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(false);
    private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();

    private void write(){
        System.out.println(Thread.currentThread().getName() + "开始尝试获取写锁");
        writeLock.lock();
        try {
            System.out.println("线程"+Thread.currentThread().getName()+"获得写锁");
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println(Thread.currentThread().getName() + "释放写锁");
            writeLock.unlock();
        }

    }

    private void read(){
        System.out.println(Thread.currentThread().getName() + "开始尝试获取读锁");
        readLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "得到了读锁，正在读取");
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println(Thread.currentThread().getName() + "释放读锁");
            readLock.unlock();
        }

    }

    public static void main(String[] args) {

        UnfairReadWriteLock unfairReadWriteLock = new UnfairReadWriteLock();
        new Thread(()->unfairReadWriteLock.write(),"线程1").start();
        new Thread(()->unfairReadWriteLock.read(),"线程2").start();
        new Thread(()->unfairReadWriteLock.read(),"线程3").start();
        new Thread(()->unfairReadWriteLock.write(),"线程4").start();
        //线程5创建了1000个子线程，模拟当线程1释放写锁后，线程2和线程3获取读锁后（因为有1000个子线程，此时写线程4大概率不是头结点，此时，后面的读线程可以插队，在写线程之前执行）
        new Thread(new Thread(new Runnable() {
            @Override
            public void run() {
                Thread thread[] = new Thread[1000];
                for (int i = 0; i < 1000; i++) {
                    thread[i] = new Thread(() -> unfairReadWriteLock.read(), "子线程创建的Thread" + i);
                }
                for (int i = 0; i < thread.length; i++) {
                    thread[i].start();
                }
            }
        })).start();

    }
}
